package com.my.processor.common;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Set;
/**
 * 注解处理器(Annotation Processor)是javac内置的一个用于编译时扫描和处理注解(Annotation)的工具。
 * 简单的说，在源代码编译阶段，通过注解处理器，我们可以获取源文件内注解(Annotation)相关内容。
 *
 * 由于注解处理器可以在程序编译阶段工作，所以我们可以在编译期间通过注解处理器进行我们需要的操作。
 * 比较常用的用法就是在编译期间获取相关注解数据，然后动态生成.java源文件（让机器帮我们写代码），
 * 通常是自动产生一些有规律性的重复代码，解决了手工编写重复代码的问题，大大提升编码效率。
 *
 * 编译期间，修改源码
 *
 * https://blog.csdn.net/kaifa1321/article/details/79683246
 * @author timo 2021/2/18
 */
public abstract class AbstractLogProcessor extends AbstractProcessor {
    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    @Override
    public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
        try {
            return this.processImpl(annotations, roundEnv);
        } catch (Exception e) {
            this.fatalError(e);
            return false;
        }
    }

    protected abstract boolean processImpl(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv);

    protected void log(final String msg) {
//        if (this.processingEnv.getOptions().containsKey("debug")) {
            this.processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, msg);
//        }
    }

    protected void error(final String msg, final Element element, final AnnotationMirror annotation) {
        this.processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg, element, annotation);
    }

    protected void fatalError(final Exception e) {
        final StringWriter writer = new StringWriter();
        e.printStackTrace(new PrintWriter(writer));
        this.fatalError(writer.toString());
    }

    protected void fatalError(final String msg) {
        this.processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "FATAL ERROR: " + msg);
    }
}


//public interface ProcessingEnvironment {
//
//    /**
//     * 返回用来在元素上进行操作的某些实用工具方法的实现。<br>
//     *
//     * Elements是一个工具类，可以处理相关Element（包括ExecutableElement, PackageElement, TypeElement, TypeParameterElement, VariableElement）
//     */
//    Elements getElementUtils();
//
//    /**
//     * 返回用来报告错误、警报和其他通知的 Messager。
//     */
//    Messager getMessager();
//
//    /**
//     *  用来创建新源、类或辅助文件的 Filer。
//     */
//    Filer getFiler();
//
//    /**
//     *  返回用来在类型上进行操作的某些实用工具方法的实现。
//     */
//    Types getTypeUtils();
//
//    // 返回任何生成的源和类文件应该符合的源版本。
//    SourceVersion getSourceVersion();
//
//    // 返回当前语言环境；如果没有有效的语言环境，则返回 null。
//    Locale getLocale();
//
//    // 返回传递给注释处理工具的特定于 processor 的选项
//    Map<String, String> getOptions();
//}
